#include <memory>
#include "tcp_client.h"

#include <iomanip>

void tcp_client::on_read_header_complete(boost::system::error_code ec, std::size_t length)
{
    if (ec) {
        return;
    }

    readed_header_size_ += length;
    /* 已经读取的数据不够组成一个消息头，继续读取消息头，刷新已经读取消息头的大小 */
    if (readed_header_size_ < NET_MESSAGE_HEADER_SIZE) {
        read_header();
        return;
    } else if (readed_header_size_ == NET_MESSAGE_HEADER_SIZE) {
        /* 已读取到一个完整的消息头，解析消息头，读取消息体 */
        memcpy(&cur_msg_header_, msg_header_buf_, NET_MESSAGE_HEADER_SIZE);
        read_body(current_body_size());
        readed_header_size_ = 0;
    }
}

int tcp_client::read_header()
{
    auto self = shared_from_this();
    socket_.async_read_some(
        net::buffer(msg_header_buf_ + readed_header_size_, NET_MESSAGE_HEADER_SIZE - readed_header_size_),
        [this, self](boost::system::error_code ec, std::size_t length) {
            if (ec) {
                std::cerr << "read error form socket" << std::endl;
                socket_.close();
            }
            on_read_header_complete(ec, length);
        });

    return NET_EC_OK;
}

void tcp_client::on_read_body_complete(boost::system::error_code ec, std::size_t length)
{
    if (ec) {
        return;
    }

    readed_body_size_ += length;
    if (readed_body_size_ < current_body_size()) {
        read_body(current_body_size() - readed_body_size_);
        return;
    } else if (readed_body_size_ == current_body_size()) {
        /* 已读取到一个完整的消息体，处理消息体 */
        std::string msg_body(msg_body_buf_, current_body_size());
        network_message msg(cur_msg_header_.msg_type_, msg_body);

        /* 处理消息 */
        network_message_handler &handler = network_message_handler::get_instance();
        // handler.handle_message(shared_from_this(), msg);
        readed_body_size_ = 0;

        /* 继续读取消息头 */
        read_header();
    }
}

int tcp_client::read_body(uint16_t size_to_read)
{
    auto self = shared_from_this();
    socket_.async_read_some(net::buffer(msg_body_buf_ + readed_body_size_, size_to_read),
        [this, self](boost::system::error_code ec, std::size_t length) {
            if (ec) {
                std::cerr << "read error form socket" << std::endl;
                socket_.close();
            }
            on_read_body_complete(ec, length);
        });
    return NET_EC_OK;
}

int tcp_client::send_message(const std::string &msg)
{
    int msg_size = msg.size();
    auto self = shared_from_this();
    socket_.async_write_some(net::buffer(msg),
        [this, self, msg](boost::system::error_code ec, std::size_t length) {
            if (ec) {
                return;
            }
            if (length < msg.size()) {
                /* 消息未发送完全 */
                send_message(msg.substr(length));
            } else {
                /* 完整消息已发出 */
                std::cout << "send a msg to server" << std::endl;
                for (auto c : msg) {
                    std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)(uint8_t)c << ' ';
                }
                std::cout << std::endl;
            }
        });

    return NET_EC_OK;
}
